#include "hidbox/hid_device_manager.h"
#include <stdexcept>
#include "base/logging.h"

namespace hidbox {

HIDDeviceManager::HIDDeviceManager() {
    gadget = std::make_unique<UsbGadget>();
    output_device = std::make_unique<OutputHIDDevice>();
}

HIDDeviceManager::~HIDDeviceManager() {
    StopPassthrough();
}

void HIDDeviceManager::Configure(const HIDDeviceConfig& config) {
    current_config = config;
    gadget->SetGadgetName(config.gadget_name);

    if (config.auto_detect) {
        ConfigureWithAutoDetect(config);
    } else {
        ConfigureWithCustom(config);
    }
}

void HIDDeviceManager::ConfigureWithAutoDetect(const HIDDeviceConfig& config) {
    LOG_INFO("Configuring HID device with auto-detection");
    LOG_INFO("Target VID={:#x} PID={:#x}",
             config.input_identifier.vid, config.input_identifier.pid);

    // 创建并打开输入设备
    input_device = std::make_unique<InputHIDDevice>(config.input_identifier);
    input_device->Open();

    // 获取设备描述符
    const auto& desc = input_device->GetDescriptor();
    LOG_INFO("Detected device: {} - {}", desc.manufacturer, desc.product);

    // 配置 USB Gadget
    gadget->Configure(desc);

    // 打开输出设备
    output_device->Open(config.hid_number);
    LOG_INFO("HID device configured successfully");
}

void HIDDeviceManager::ConfigureWithCustom(const HIDDeviceConfig& config) {
    LOG_INFO("Configuring HID device with custom configuration");

    if (config.custom.report_descriptor.empty()) {
        throw std::runtime_error("Custom report descriptor cannot be empty");
    }

    // 构建自定义描述符
    HIDGadgetDescriptor desc{};
    desc.bcd_usb = 0x0200;
    desc.device_subclass = 0;
    desc.device_protocol = 0;
    desc.max_packet_size0 = 64;
    desc.vendor_id = config.custom.vendor_id;
    desc.product_id = config.custom.product_id;
    desc.bcd_device = 0x0100;
    desc.manufacturer = config.custom.manufacturer;
    desc.product = config.custom.product;
    desc.serial = config.custom.serial;
    desc.hid_protocol = 2;  // Mouse
    desc.hid_subclass = 1;   // Boot Interface
    desc.report_descriptor_data = config.custom.report_descriptor;
    desc.report_length = 64;  // 默认报告长度

    LOG_INFO("Custom device: {} - {}", desc.manufacturer, desc.product);

    // 配置 USB Gadget
    gadget->Configure(desc);

    // 打开输出设备
    output_device->Open(config.hid_number);
    LOG_INFO("Custom HID device configured successfully");
}

void HIDDeviceManager::StartPassthrough() {
    if (is_passthrough_active) {
        LOG_WARNING("Passthrough is already active");
        return;
    }

    if (!input_device) {
        throw std::runtime_error("Input device not configured. Use auto_detect mode.");
    }

    LOG_INFO("Starting HID passthrough");

    // 设置输入回调
    input_device->SetInputCallback([this](u8* data, u32 length) {
        OnInputData(data, length);
    });

    // 开始读取输入
    input_device->StartReadInput();
    is_passthrough_active = true;
    LOG_INFO("HID passthrough started");
}

void HIDDeviceManager::StopPassthrough() {
    if (!is_passthrough_active) {
        return;
    }

    LOG_INFO("Stopping HID passthrough");
    if (input_device) {
        input_device->StopReadInput();
    }
    is_passthrough_active = false;
    LOG_INFO("HID passthrough stopped");
}

ssize_t HIDDeviceManager::WriteToOutput(const void* data, size_t size) {
    if (!output_device || !output_device->IsOpened()) {
        LOG_ERROR("Output device not opened");
        return -1;
    }
    return output_device->Write(data, size);
}

void HIDDeviceManager::OnInputData(u8* data, u32 length) {
    // 转发到输出设备（透传）
    if (output_device && output_device->IsOpened()) {
        output_device->Write(data, length);
    }

    // 调用用户回调
    if (input_callback) {
        input_callback(data, length);
    }
}

const HIDGadgetDescriptor* HIDDeviceManager::GetInputDescriptor() const {
    if (input_device) {
        return &input_device->GetDescriptor();
    }
    return nullptr;
}

}  // namespace hidbox
